package service

import (
	"admin-api/app/dao"
	"admin-api/app/models/entity"
	"admin-api/app/models/request"
	"admin-api/app/models/response"
	"admin-api/core"
	"admin-api/utils"
	"gitee.com/molonglove/goboot/gorm"
	"time"
)

var Dept = new(DeptService)

type DeptService struct{}

// Tree 部门数
func (s *DeptService) Tree() ([]*response.DeptTree, *response.BusinessError) {
	var (
		recursionBuild func(pId int64, data []entity.Dept) []*response.DeptTree
		tree           []*response.DeptTree
		all            []entity.Dept
		err            error
	)
	// 递归构建树
	recursionBuild = func(pId int64, data []entity.Dept) []*response.DeptTree {
		var children []*response.DeptTree
		for _, item := range data {
			if pId == item.ParentId {
				child := &response.DeptTree{
					Key:   item.DeptId,
					Label: item.DeptName,
				}
				child.Children = recursionBuild(item.DeptId, data)
				children = append(children, child)
			}
		}
		return children
	}
	if err = core.DB.Builder().
		Select().
		From("sys_dept").
		Where(gorm.Eq("del_flag", 1)).
		QExecute(&all).
		Error; err != nil {
		core.Log.Error("获取部门数据发生异常：%s", err.Error())
		return nil, response.CustomBusinessError(response.Failed, "获取部门数据失败")
	}
	if len(all) <= 0 {
		return make([]*response.DeptTree, 0), nil
	}
	tree = recursionBuild(0, all)
	return tree, nil
}

// Table 部门树表
func (s *DeptService) Table(param *request.DeptTableQueryRequest) ([]response.DeptTableResponse, *response.BusinessError) {
	var (
		recursionBuild func(pId int64, data []response.DeptTableResponse) []response.DeptTableResponse
		result         []response.DeptTableResponse
		err            error
	)
	// 递归构建树
	recursionBuild = func(pId int64, data []response.DeptTableResponse) []response.DeptTableResponse {
		var children []response.DeptTableResponse
		for _, item := range data {
			if pId == item.ParentId {
				item.Children = recursionBuild(item.DeptId, data)
				children = append(children, item)
			}
		}
		return children
	}
	if err = core.DB.Namespace("dept").
		DQuery("selectByDept", param).
		TSelect(&result).
		Error; err != nil {
		core.Log.Error("获取部门数据发生异常：%s", err.Error())
		return nil, response.CustomBusinessError(response.Failed, "获取部门数据失败")
	}
	if len(result) <= 0 {
		return result, nil
	}
	if param.Name == "" {
		result = recursionBuild(0, result)
	}
	return result, nil
}

// Create 部门创建
func (s *DeptService) Create(param *request.DeptCreateRequest) *response.BusinessError {
	var (
		dept entity.Dept
		now  time.Time
		err  error
	)
	// 检测菜单名称是否唯一
	if dao.Dept.ExistSameDept(param.DeptName, param.ParentId, 0) {
		core.Log.Error("存在相同的部门名称")
		return response.CustomBusinessError(response.Failed, "存在相同的部门名称")
	}
	now = time.Now()
	_ = utils.StructCopy(param, &dept)
	dept.CreateTime, dept.CreateBy = &now, param.UserName
	if err = core.DB.Create(&dept).Error; err != nil {
		return response.CustomBusinessError(response.Failed, "创建部门失败")
	}
	core.Log.Info("创建部门[%d:%s]成功", dept.DeptId, dept.DeptName)
	return nil
}

// Update 部门更新
func (s *DeptService) Update(param *request.DeptUpdateRequest) *response.BusinessError {
	var (
		err error
	)
	// 检测部门名称是否唯一
	if dao.Dept.ExistSameDept(param.DeptName, param.ParentId, param.DeptId) {
		core.Log.Error("存在相同的部门名称")
		return response.CustomBusinessError(response.Failed, "存在相同的部门名称")
	}
	if err = core.DB.Namespace("dept").
		DUpdate("updateDept", param).
		TUpdate(map[string]any{"DeptId": param.DeptId}).
		Error; err != nil {
		core.Log.Error("更新部门信息失败: %s", err.Error())
		return response.CustomBusinessError(response.Failed, "更新部门失败")
	}
	core.Log.Info("更新部门信息成功")
	return nil
}

// Info 部门详情
func (s *DeptService) Info(deptId int64) (*response.DeptInfoResponse, *response.BusinessError) {
	var (
		result response.DeptInfoResponse
		dept   entity.Dept
		err    error
	)
	if err = core.DB.Builder().
		Select().
		From("sys_dept").
		Where(gorm.Eq("dept_id", deptId), gorm.Eq("del_flag", 1)).
		QExecute(&dept).Error; err != nil {
		core.Log.Info("获取部门失败：%s", err.Error())
		return nil, response.CustomBusinessError(response.Failed, "获取部门失败")
	}
	_ = utils.StructCopy(dept, &result)
	return &result, nil
}

// Delete 部门删除
func (s *DeptService) Delete(deptId int64, username string) *response.BusinessError {
	var (
		num int64
		err error
	)
	// 部门是否存在下级部门
	if err = core.DB.Builder().
		Select(gorm.Count("1")).
		From("sys_dept").
		Where(gorm.Eq("parent_id", deptId), gorm.Eq("del_flag", 1)).
		QExecute(&num).
		Error; err != nil || num > 0 {
		if err != nil {
			core.Log.Error("判断是否存下级机构错误: %s", err.Error())
		}
		return response.CustomBusinessError(response.Failed, "部门存在下级部门")
	}
	if err = core.DB.Builder().
		Select(gorm.Count("1")).
		From("sys_user").
		Where(gorm.Eq("dept_id", deptId), gorm.Eq("del_flag", 1)).
		QExecute(&num).Error; err != nil {
		if err != nil {
			core.Log.Error("判断是否存在用户错误: %s", err.Error())
		}
		return response.CustomBusinessError(response.Failed, "部门下存在用户")
	}
	if err = core.DB.Builder().
		Delete().
		From("sys_dept").
		Where(gorm.Eq("dept_id", deptId)).
		DExecute().
		Error; err != nil {
		core.Log.Error("删除部门失败：%s", err.Error())
		return response.CustomBusinessError(response.Failed, "删除部门失败")
	}
	return nil
}
